﻿
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace SignalR.Controllers
{
    public static class ListManager
    {

        public static MemoryStream Export<TSource>(this IEnumerable<TSource> source, string[] headArray = null, Action<ISheet> actionSheet = null)
        {
            if (source == null || source.Count() == 0)
            {
                return new MemoryStream();
            }
            var t = source.First().GetType();
            if (!t.IsClass || t.GetProperties().Length == 0)
                return new MemoryStream();

            const int maxSheetCount = 65530;
            HSSFWorkbook workbook = new HSSFWorkbook();
            MemoryStream ms = new MemoryStream();

            int Count = source.Count() / maxSheetCount;

            for (int i = 0; i <= Count; i++)
            {
                ISheet sheet = workbook.CreateSheet("sheet" + i.ToString());

                ICellStyle style = workbook.CreateCellStyle();
                var font = workbook.CreateFont();
                font.IsBold = true;

                style.VerticalAlignment = VerticalAlignment.Center;
                style.Alignment = HorizontalAlignment.Center;
                style.SetFont(font);

                IRow headerRow1 = sheet.CreateRow(0);
                headerRow1.Height = 300;
                var pros = t.GetProperties();

                // 表格头部 
                if (headArray?.Length <= 0)
                {
                    headArray = new string[pros.Length];
                    for (int h = 0; h < pros.Length; h++)
                    {
                        headArray[h] = pros[h].Name;
                    }
                }
                //headerRow1.CreateCell(0).SetCellValue("姓名");

                //headerRow1.CreateCell(1).SetCellValue("联系方式");
                //headerRow1.GetCell(1).CellStyle = style;
                //headerRow1.RowStyle = style;

                IRow headerRow2 = sheet.CreateRow(0);
                headerRow1.RowStyle = style;
                for (int h = 0; h < headArray.Length; h++)
                {
                    headerRow2.CreateCell(h).SetCellValue(headArray[h]);
                    headerRow2.Cells[h].CellStyle = style;
                    headerRow2.Height = 300;
                }

                ////合并头部列、行
                //sheet.AddMergedRegion(new CellRangeAddress(0, 1, 0, 0));
                //sheet.AddMergedRegion(new CellRangeAddress(0, 0, 1, 3));

                //List<KeyValuePair<int, string>> nameIndexList = new List<KeyValuePair<int, string>>();
                int rowIndex = 1;
                for (int j = maxSheetCount * i; j < maxSheetCount * (i + 1); j++)
                {
                    if (j >= source.Count() || rowIndex >= maxSheetCount)
                    {
                        break;
                    }
                    IRow dataRow = sheet.CreateRow(rowIndex);
                    dataRow.Height = 300;
                    for (int m = 0; m < pros.Length; m++)
                    {
                        var s = pros[m].GetValue(source.ElementAt(j)).ToString();
                        dataRow.CreateCell(m).SetCellValue(s);
                        dataRow.Cells[0].CellStyle.VerticalAlignment = VerticalAlignment.Center;
                        dataRow.Cells[0].CellStyle.VerticalAlignment = VerticalAlignment.Center;
                        sheet.SetColumnWidth(m, 5000);
                    }
                    rowIndex++;
                }
                //var names = nameIndexList.Select(c => c.Value).Distinct().ToList();
                //foreach (var item in names)
                //{
                //    var startIndex = nameIndexList.Where(c => c.Value == item).Min(c => c.Key);
                //    var endIndex = nameIndexList.Where(c => c.Value == item).Max(c => c.Key);
                //    if (endIndex > startIndex)
                //    {
                //        sheet.AddMergedRegion(new CellRangeAddress(startIndex, endIndex, 0, 0));
                //    }
                //}
                if (actionSheet != null)
                {
                    actionSheet.Invoke(sheet);
                }
            }
            workbook.Write(ms);
            return ms;
        }
    }
}
